/**
 * API Server Tests
 * 
 * Tests for HTTP API endpoints
 */

import { describe, test, expect } from 'bun:test';
import { createApp } from '../src/api/server';

describe('API Server', () => {
  const app = createApp();

  describe('Health Check', () => {
    test('GET /health should return healthy status', async () => {
      const req = new Request('http://localhost/health');
      const res = await app.fetch(req);

      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.status).toBe('healthy');
      expect(data.version).toBeDefined();
      expect(data.uptime).toBeGreaterThanOrEqual(0);
    });
  });

  describe('Session Routes', () => {
    test('POST /api/session/create should create a session', async () => {
      const req = new Request('http://localhost/api/session/create', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          agentOptions: { model: 'claude-sonnet-4' },
          metadata: { test: true },
        }),
      });

      const res = await app.fetch(req);
      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.success).toBe(true);
      expect(data.data.id).toBeDefined();
      expect(data.data.agentOptions.model).toBe('claude-sonnet-4');
    });

    test('GET /api/session should list sessions', async () => {
      const req = new Request('http://localhost/api/session');
      const res = await app.fetch(req);

      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.success).toBe(true);
      expect(Array.isArray(data.data)).toBe(true);
    });
  });

  describe('Tool Routes', () => {
    test('GET /api/tools should list tools', async () => {
      const req = new Request('http://localhost/api/tools');
      const res = await app.fetch(req);

      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.success).toBe(true);
      expect(Array.isArray(data.data)).toBe(true);
    });

    test('GET /api/tools/:name should return 404 for non-existent tool', async () => {
      const req = new Request('http://localhost/api/tools/nonexistent');
      const res = await app.fetch(req);

      expect(res.status).toBe(404);

      const data = await res.json();
      expect(data.success).toBe(false);
      expect(data.error?.code).toBe('TOOL_NOT_FOUND');
    });
  });

  describe('MCP Routes', () => {
    test('GET /api/mcp/servers should list MCP servers', async () => {
      const req = new Request('http://localhost/api/mcp/servers');
      const res = await app.fetch(req);

      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.success).toBe(true);
      expect(Array.isArray(data.data)).toBe(true);
    });

    test('POST /api/mcp/servers should register MCP server', async () => {
      const req = new Request('http://localhost/api/mcp/servers', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: 'test-server',
          config: {
            type: 'stdio',
            command: 'node',
            args: ['server.js'],
          },
        }),
      });

      const res = await app.fetch(req);
      expect(res.status).toBe(200);

      const data = await res.json();
      expect(data.success).toBe(true);
      expect(data.data.name).toBe('test-server');
    });
  });

  describe('Error Handling', () => {
    test('should return 404 for unknown routes', async () => {
      const req = new Request('http://localhost/unknown');
      const res = await app.fetch(req);

      expect(res.status).toBe(404);

      const data = await res.json();
      expect(data.success).toBe(false);
      expect(data.error?.code).toBe('NOT_FOUND');
    });

    test('should handle invalid JSON gracefully', async () => {
      const req = new Request('http://localhost/api/session/create', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: 'invalid json',
      });

      const res = await app.fetch(req);
      expect(res.status).toBe(500);

      const data = await res.json();
      expect(data.success).toBe(false);
    });
  });
});

